/// 本文件由reazhuang@outlook.com开发编写 *CodeMaid自动格式化*
/// 只用做多选使用
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;

namespace ReaWTM.LayuiHelper
{
	[HtmlTargetElement("wt:checkbox", Attributes = REQUIRED_ATTR_NAME, TagStructure = TagStructure.WithoutEndTag)]
	public class CheckBoxTagHelper : BaseFieldTag
	{
		private Type _modelType;

		/// <summary>
		/// 改变选择时触发的js函数，func(data)格式;
		/// <para>
		/// data.elem得到checkbox原始DOM对象
		/// </para>
		/// <para>
		/// data.elem.checked是否被选中，true或者false
		/// </para>
		/// <para>
		/// data.value复选框value值，也可以通过data.elem.value得到
		/// </para>
		/// <para>
		/// othis得到美化后的DOM对象
		/// </para>
		/// </summary>
		public string ChangeFunc { get; set; }

		public bool IsPrimary { get; set; } = true;

		/// <summary>
		/// 选项
		/// </summary>
		public ModelExpression Items { get; set; }

		public string TextKey { get; set; } = "Text";

		public string ValueKey { get; set; } = "Value";

		public override void Process(TagHelperContext context, TagHelperOutput output)
		{
			_modelType = Field.Metadata.ModelType;
			if (!_modelType.IsList())
			{
				throw new Exception("wt:checkbox只用于绑定列表");
			}
			output.TagName = "input";
			output.TagMode = TagMode.StartTagOnly;
			output.Attributes.Add("type", "hidden");
			output.Attributes.Add("wtm-verify", "这是一个隐藏验证表单");

			StringBuilder builder = new StringBuilder();

			builder.Append($@"
<script>
wtm.checkbox_Render({{
id:'{Id}',
url:'{ItemUrl}',
data:{GetItems()},
value:{GetDefaultValue()},
fieldName:'{GetName(context)}',
textKey:'{TextKey}',
valueKey:'{ValueKey}',
skin:'{(IsPrimary ? "primary" : "")}',
changeFunc:'{ChangeFunc}',
beforeMount:'{BeforeMount}',
mounted:'{Mounted}',
}});
</script>
");
			output.PostElement.AppendHtml(builder.ToString());
			base.Process(context, output);
		}

		protected override void SetName(TagHelperContext context, TagHelperOutput output)
		{
			return;
		}

		protected override string GetDefaultValue()
		{
			if (Field.Model != null)
			{
				DefaultValue = JsonSerializer.Serialize(Field.Model, JsonOptions2);
			}

			if (string.IsNullOrEmpty(DefaultValue))
			{
				return "''";
			}

			if (!DefaultValue.StartsWith("["))
			{
				DefaultValue = $"[{DefaultValue}]";
			}
			return DefaultValue;
		}

		private string GetItems()
		{
			if (!string.IsNullOrEmpty(ItemUrl)) return "[]";

			var modelType = Field.Metadata.ModelType;
			var listItems = new List<ComboSelectListItem>();
			if (Items?.Model == null)
			{
				if (modelType.IsList())
				{
					var innerType = modelType.GetGenericArguments()[0];
					if (innerType.IsEnumOrNullableEnum())
					{
						listItems = innerType.ToListItems();
					}
				}
				else if (modelType.IsBoolOrNullableBool())
				{
					listItems = new List<ComboSelectListItem>() { new ComboSelectListItem { Value = "true", Text = "|" } };
				}
			}
			else
			{
				if (typeof(IEnumerable<ComboSelectListItem>).IsAssignableFrom(Items.Metadata.ModelType))
				{
					if (typeof(IEnumerable<TreeSelectListItem>).IsAssignableFrom(Items.Metadata.ModelType))
					{
						listItems = (Items.Model as IEnumerable<TreeSelectListItem>).FlatTreeSelectList().Cast<ComboSelectListItem>().ToList();
					}
					else
					{
						listItems = (Items.Model as IEnumerable<ComboSelectListItem>).ToList();
					}
				}
				else if (Items.Metadata.ModelType.IsList())
				{
					var exports = (Items.Model as IList);
					foreach (var item in exports)
					{
						listItems.Add(new ComboSelectListItem
						{
							Text = item?.ToString(),
							Value = item?.ToString()
						});
					}
				}
			}
			return JsonSerializer.Serialize(listItems, JsonOptions2);
		}
	}
}